package com.shawn.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * @author Shawn_Zhou
 */
@Aspect
@Component
public class MyAspect {

    @Before("execution(* com.shawn.*.*.*(..))")
    public void before(JoinPoint joinPoint) {
        //@Before 用在方法上代表这个方法是一个前置通知方法  注解的参数是切点表达式
        System.out.println("前置通知");
        //JoinPoint 通过该对象可以获取到被切入的对象的信息
        joinPoint.getTarget();//目标对象
        joinPoint.getSignature();//方法签名
        joinPoint.getArgs();//方法参数
    }

    @After("execution(* com.shawn.*.*.*(..))")
    public void after(JoinPoint joinPoint) {
        //@Before 用在方法上代表这个方法是一个前置通知方法  注解的参数是切点表达式
        System.out.println("后置通知");
        //JoinPoint 通过该对象可以获取到被切入的对象的信息
        joinPoint.getTarget();//目标对象
        joinPoint.getSignature();//方法签名
        joinPoint.getArgs();//方法参数
    }

    @Around("execution(* com.shawn.*.*.*(..))")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //@Before 用在方法上代表这个方法是一个前置通知方法  注解的参数是切点表达式
        System.out.println("环绕通知");
        //JoinPoint 通过该对象可以获取到被切入的对象的信息
        proceedingJoinPoint.getTarget();//目标对象
        proceedingJoinPoint.getSignature();//方法签名
        proceedingJoinPoint.getArgs();//方法参数
        //放行执行目标方法  这一步必须存在，否则后续方法不会执行
        Object proceed = proceedingJoinPoint.proceed();
        System.out.println("目标方法执行之后回到环绕通知");
        return proceed;
    }

}
